using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using Microsoft.Win32;
using System.Diagnostics;

class SecuritySettings
{
    // Class member variables
    private string          m_membershipUrl;
    private string          m_redirectUrl;
    private string          m_publisher;
    private string          m_description;
    private string          m_name;
    private PermissionSet   m_permission;
    
    // The URL that is used to patch the security config file
    public string MembershipUrl
    {
        get { return m_membershipUrl; }
        set { m_membershipUrl = value; }
    }

    // The URL that is used to redirect the IE
    public string RedirectUrl
    {
        get { return m_redirectUrl; }
        set { m_redirectUrl = value; }
    }

    // The publisher name
    public string Publisher
    {
        get { return m_publisher; }
        set { m_publisher = value; }
    }

    // The name that is displayed in the security configuration wizard
    public string Name
    {
        get { return m_name; }
        set { m_name = value; }
    }

    // The decription that is displayed in the security configuration wizard
    public string Description
    {
        get { return m_description; }
        set { m_description = value; }
    }

    // The permission set
    public PermissionSet Permission
    {
        get { return m_permission; }
        set { m_permission = value; }
    }

    public bool Patch()
    {
        try
        {
            // patch Registry according to http://msdn.microsoft.com/en-us/library/hh367887.aspx
            if(Read("SOFTWARE\\Microsoft\\.NETFramework") == true)
                Write("SOFTWARE\\Microsoft\\.NETFramework", "EnableIEHosting", 1);
            if (Read("SOFTWARE\\Wow6432Node\\Microsoft\\.NETFramework") == true)
                Write("SOFTWARE\\Wow6432Node\\Microsoft\\.NETFramework", "EnableIEHosting", 1);

            // get .NET directory
            RegistryKey hklm = Registry.LocalMachine;
            hklm = hklm.OpenSubKey("SOFTWARE\\Microsoft\\.NETFramework");
            string DOTNET_INSTALLROOT = hklm.GetValue("InstallRoot").ToString();

            // use 32bit Framework
            if (DOTNET_INSTALLROOT.Contains("Framework64"))
                DOTNET_INSTALLROOT = DOTNET_INSTALLROOT.Replace("64", "");

            DirectoryInfo dotnetDir = new DirectoryInfo(DOTNET_INSTALLROOT);
            DirectoryInfo[] frameworkDirs = dotnetDir.GetDirectories();

            // get directly with caspol > 3.0
            foreach (DirectoryInfo dir in frameworkDirs)
            {
                if (dir.Name.StartsWith("v3.0"))
                    continue;

                switch (dir.Name.Substring(0, 4))
                {
                    case "v2.0":
                        dotnetDir = new DirectoryInfo(DOTNET_INSTALLROOT + dir.Name);
                        break;
                    case "v1.1":
                        dotnetDir = new DirectoryInfo(DOTNET_INSTALLROOT + dir.Name);
                        break;
                    case "v1.0":
                        dotnetDir = new DirectoryInfo(DOTNET_INSTALLROOT + dir.Name);
                        break;
                }
            }

            // arguments for the machine level
            string argsMachineLevel = "-polchgprompt off -q -machine -addgroup 1. -url ";
            argsMachineLevel += m_membershipUrl + " ";
            argsMachineLevel += m_permission + " ";
            argsMachineLevel += "-n " + "\"" + m_name + "\" ";
            argsMachineLevel += "-description " + "\"" + m_description + "\"";

            // new process for the machine level
            // a process is required to elevate the user rights on Win 7 and Vista
            Process casPolMachineLevel = new Process();
            casPolMachineLevel.StartInfo.UseShellExecute = true;
            casPolMachineLevel.StartInfo.Verb = "runas";
            casPolMachineLevel.StartInfo.Arguments = argsMachineLevel;
            casPolMachineLevel.StartInfo.FileName = dotnetDir.FullName + "\\caspol";
            casPolMachineLevel.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            casPolMachineLevel.Start();

            // user level
            string argsUserLevel = "-polchgprompt off -q -u -addgroup 1. -url ";
            argsUserLevel += m_membershipUrl + " ";
            argsUserLevel += m_permission + " ";
            argsUserLevel += "-n " + "\"" + m_name + "\" ";
            argsUserLevel += "-description " + "\"" + m_description + "\"";

            Process casPolUserLevel = new Process();
            casPolUserLevel.StartInfo.UseShellExecute = true;
            casPolUserLevel.StartInfo.Verb = "runas";
            casPolUserLevel.StartInfo.Arguments = argsUserLevel;
            casPolUserLevel.StartInfo.FileName = dotnetDir.FullName + "\\caspol";
            casPolUserLevel.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            casPolUserLevel.Start();

            return true;
        }
        catch (Exception exc)
        {
            throw exc;
        }
    }

    // restart IE and open a new browser instance with the 
    public void RestartIE()
    {
        try
        {
            Process[] curIEProcesses = Process.GetProcessesByName("iexplore");

            foreach (Process IEProcess in curIEProcesses)
            {
                IEProcess.Kill();
            }

            Process newBrowser = new Process();
            newBrowser.StartInfo.FileName = "iexplore.exe";
            newBrowser.StartInfo.Arguments = m_redirectUrl;
            newBrowser.Start();
        }
        catch (Exception exc)
        {
            throw exc;
        }
    }

    public bool Read(string SubKey)
    {
        // Opening the registry key
        RegistryKey rk = Registry.LocalMachine;
        // Open a subKey as read-only
        RegistryKey sk1 = rk.OpenSubKey(SubKey);
        // If the RegistrySubKey doesn't exist -> (null)
        if (sk1 == null)
        {
            return false;
        }

        return true;
    }

    public bool Write(string SubKey, string KeyName, object Value)
    {
        try
        {
            // Setting
            RegistryKey rk = Registry.LocalMachine;
            RegistryKey sk1 = rk.CreateSubKey(SubKey);
            // Save the value
            sk1.SetValue(KeyName.ToUpper(), Value, RegistryValueKind.DWord);

            return true;
        }
        catch (Exception e)
        {
            return false;
        }
    }
}

public enum PermissionSet
{
    LocalIntranet,
    Internet,
    SkipVerification,
    Execution,
    Nothing,
    Everything,
    FullTrust
}
